/*
 * Matthew Cramer, Jesse Martinez, Marc Mendoza 
 * CSE 325 Lab 4
 * File: TestingInterface.c
 * Description: Manager that handles calls to the Queue Manager and IPC Manager.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "../QueueManager/QueueManager.h"
#include "../IPCManager/IPCManager.h"
#define MAX_QUEUE_SIZE 10
void list(int);

int  main(int argc, char *argv[])
{
	char command[500], manager[10][20];
	char argument[3] [30];
	char *temp;
	int exit = 1, check=0, manualInput = 1, initiate=0;
	int i=0;//total managers
	FILE *file;
	
    //Open File for Use
	if(argc == 2)
	{
		file = fopen(argv[1], "r");
		manualInput =0;
	}
	
	while(exit != 0)
	{
        //Display Menu
		printf("\nCommunication: \n");
		printf("1) init_IPC manager1 manager2 [manager3,…,manager10]\n");
		printf("2) List [Queuename]\n");
		printf("3) HAS_Message Queuename\n");
		printf("4) Send source destination message\n");
		printf("5) Retrieve destination\n");
		printf("6) EXIT\n");
		printf("\n");
		
        //For terminal use
		if(manualInput == 1)
		{
			scanf("%[^\n]",command);
			getchar();
		}
		
        //For input file use
		else if(manualInput == 0)
		{

            if (fgets(command, sizeof command, file)) 
            {
                char* p = strchr(command,'\n');
                if (p)
                    *p = '\0';
                printf("%s\n", command);
            }
		}
		
		//uses a string tokenizer to split files based on whitespace
		temp = strtok(command, " ");
		
		strcpy(command, temp);
		
        //If command is init_IPC
		if(strcmp(command, "init_IPC") == 0)
		{
			int k=0;
			temp = strtok(NULL, " ");
			//puts all managers into array
            
            //Check to see if correct number of arguments
			while(temp != NULL)
			{
				strcpy(manager[k], temp);
				temp = strtok(NULL, " ");
				k++;
			}

			if(k >10 || k<2)
			{
				printf("\nERROR: NEED BETWEEN 2 AND 10 MANAGERS\n");
			}
            //If correct number of arguments, allocate queues
			else
			{
                i=k;
				//below checks for unique managers
				int x,z;
				for(x=0; x<i; x++)
				{
					for(z=x+1; z<i; z++)
					{
						if(strcmp(manager[x],manager[z]) == 0)
						{
							check =1;
							if(check == 1)
							{	
								break;
							}
						}
					
					}
					if(check == 1)
					{
						break;
					}
				}
				if(check == 1)
				{
					printf("\nERROR: MANAGERS ARE NOT UNIQUE\n");
                    check=0;
				}
				else
				{
					clearQueues(i);
                    initiate=1;
				}
			}
		}
        //If Command is List
		else if(strcmp(command, "List") == 0 && initiate==1)
		{
			temp = strtok(NULL, " ");
            int k=0;
            //Check to see if arguments are correct
            while(temp != NULL)
			{
				strcpy(argument[k], temp);
				temp = strtok(NULL, " ");
				k++;
			}
            //If queue requested, check to see if manager is being used
			if(k == 1)
			{
				int x=0,y=0;
                printf("\n");
				while(x < i && y != 1)
                {
					if(strcmp(argument[0], manager[x])==0)
					{
						printf("%s\n",manager[x]);
						list(x+1);
                        y=1;
					}
                    x++;
				}
				if(y==0)
				{
					printf("ERROR: MANAGER NOT IN USE\n");
				}
			}
            //List all managers being used
			else if( temp == NULL)
			{
				int x;
                printf("\n");
				for(x= 0; x<i; x++)
				{
					printf("\n%s\n", manager[x]);
                    list(x+1);
                    printf("\n");
				}
			}
            else
              printf("\nERROR: INCORRECT ARGUMENTS\n");  
		}
        //If command is HAS_Message
		else if(strcmp(command, "HAS_Message") == 0 && initiate==1)
		{
			temp = strtok(NULL, " ");
            int k=0;
            //Check to see if correct number of arguments
            while(temp != NULL)
			{
				strcpy(argument[k], temp);
				temp = strtok(NULL, " ");
				k++;
			}
			if(k == 1)
			{
				int x;
                //Check to see if manager being used
				for(x=0; x<i; x++)
				{
                    //If manager is found, check to see if queue has elements
                    //If the queue has elements, return true, else false
					if(strcmp(argument[0], manager[x]) == 0)
					{
						int k = hasMessage(x+1);

						if(k == 1)
							printf("\nTRUE\n");
						else if(k==0)
							printf("\nFALSE\n");
						break;
					}
				}
				if(x==i)
				{
					printf("\nERROR: MANAGER NOT IN USE\n");
				}
			}
            else
                printf("\nERROR: INCORRECT ARGUMENTS\n");
		}
        //If command is Send
		else if(strcmp(command, "Send") == 0 && initiate==1)
		{
			int k = 0;
			int z =0;
			temp = strtok(NULL, " ");
            //Check to see if correct number of arguments
			while(temp != NULL)
			{
				strcpy(argument[k], temp);
				temp = strtok(NULL, " ");
				k++;
			}
			int e;
            //If not correct arguments
			if( k != 3)
			{
				printf("\nERROR: INCORRECT ARGUMENTS\n");
			}
			else
			{
				int man1=0,man2=0, z=0;
				k=0;
				
                int x;
                //Check if source manager exists
                for(x =0; x<i; x++)
                {
                    if(strcmp(argument[0], manager[x]) == 0)
                    {
                        man1 = x;
                        break;
                    }
                }

                int d;
                //check if destination manager exists
                for(d =0; d<i; d++)
                {
                 if(strcmp(argument[1], manager[d]) == 0)
                    {
                        man2 = d;
                        break;
                    }
                }

                //If source or destination don't exist, error
                if(x==i || d==i)
                {
                    z=1;
                    printf("\nERROR: MANAGER NOT IN USE\n");
                }
					
				
				if(z == 0)
				{
                    int a;
                    //checks to see if message is integer
                    if(isalpha(*argument[2]) > 0)
                        printf("ERROR: MESSAGE NOT INTEGER\n"); 
                    else
                        a = Send(man1+1,man2+1,atoi(argument[2]));
                    //If queue can receive message
                    if(a == -16)
                        printf("ERROR: DESTINATION FULL\n");
				}
				
			}
		}
        //If commnad is Retrieve
		else if(strcmp(command, "Retrieve") == 0 && initiate==1)

		{
			temp = strtok(NULL," ");
            int k=0;
            //Check to see if correct number of arguments
            while(temp != NULL)
			{
				strcpy(argument[k], temp);
				temp = strtok(NULL, " ");
				k++;
			}
			if(k== 1)
			{
					int x;
                    //Check to see if manager exists
					for(x =0; x<i; x++)
					{
						if(strcmp(argument[0], manager[x]) == 0)
						{
							break;
						}
					}
					if(x==i)
					{
						printf("\nERROR: MANAGER NOT IN USE\n");
					}
					else
					{
                        //Retreive message, report if no message in queue
                        int message = Retrieve(x+1);
                        if(message == -15)
                        {
                            printf("NO MESSAGES\n");
                        }
                        else
                        {
						printf("\nMessage: %i \n",message);
                        }
                    }
			}
            else
                printf("ERROR: INCORRECT ARGUMENTS\n");
		}
        //Exit program command
		else if(strcmp(command, "EXIT") == 0 || strcmp(command, "exit") == 0)
		{
				exit = 0;
		}
        //If init_IPC has not been called initially, error
        else if(initiate==0)
        {
            printf("\nERROR: PLEASE INITIATE QUEUES\n");
        }
        //If command not recognized, error
		else
		{
			printf("\nERROR: PLEASE ENTER COMMAND CORRECTLY\n");
		}
	}
	return 0;
}

//Lists the messages in a queue
void list(int whichQueue)
{
	int head = getHead(whichQueue), tail = getTail(whichQueue);
	int size = getSizeOfQueue(whichQueue);
	message_block *tempQueue = getQueue(whichQueue);
	if(size == 0)
	{
		printf("Empty\n");
	}
    //Get message from each node in the linked list
	else
	{
		int i =head;
		int e;
		for(e= 0; e<size; e++)
		{
			printf("%d\n", tempQueue[i].message);
			i = tempQueue[i].nextIndex;
		}
	}
	
}